#include "ml307_thread.h"
#include "cJSON.h"
#include "ml307.h"
#include "t_at_ringbuffer.h"

void ml_Task(void *parameter);  /// 上传
TaskHandle_t ml_upload_Handle = NULL;

void json_parse_Task(void *parameter);  ////解包
TaskHandle_t ml_json_parse_Handle = NULL;
rbuf MQTT_ML_data_rbuf;
void ml_Task(void *parameter) {
    rbuf_init(&MQTT_ML_data_rbuf);
    ml370_creat(&ml307_cfg);
    rdata_buff ml_payload;
    
    while (1) {
        if (rbuf_is_empty(&MQTT_ML_data_rbuf) != RBUF_EMPTY) {
            if (rbuf_pop(&MQTT_ML_data_rbuf, &ml_payload) == RBUF_OK) {
                uint8_t id_index = (uint8_t)(uintptr_t)ml_payload.arg;
                if (id_index < 4) {
                    printf("[DEBUG] Sending data (len=%d) to client %d\n", ml_payload.buf_len, id_index);
                    ml307_send_net_data(ML307R, &ml307_cfg,
                                        id_index,  // 动态ID
                                        NULL, (char *)ml_payload.buffer, ml_payload.buf_len);
                } else {
                    printf("[ERROR] Invalid client_id: %d\n", id_index);
                }
            }
        }
        vTaskDelay(pdMS_TO_TICKS(1));
    }
}

void queue_ml_send(uint8_t client_id, uint8_t *payload, uint16_t len) {
    if (payload == NULL || len == 0 || client_id >= 4) {
        printf("[ERROR] Invalid params: client_id=%d, len=%d\n", client_id, len);
        return;
    }

    rdata_buff ml_reply_data_t;
    memset(&ml_reply_data_t, 0, sizeof(rdata_buff));  // 清零

    // 确保 len 不超过缓冲区大小
    ml_reply_data_t.buf_len = (len > URC_DATA_BUFFER_SIZE) ? URC_DATA_BUFFER_SIZE : len;
    memcpy(ml_reply_data_t.buffer, payload, ml_reply_data_t.buf_len);
    ml_reply_data_t.arg = (void *)(uintptr_t)client_id;

    if (rbuf_push(&MQTT_ML_data_rbuf, &ml_reply_data_t) != RBUF_OK) {
        printf("[ERROR] Push failed for client %d\n", client_id);
    }
}
// 找到最外层的 JSON 边界
static int ml_find_outer_json_boundaries(char *input, char **start, char **end) {
    if (input == NULL || start == NULL || end == NULL) return -1;

    int brace_count = 0;       // 计数器
    char *first_brace = NULL;  // 最外层的 '{'
    char *last_brace = NULL;   // 最外层的 '}'

    for (char *p = input; *p != '\0'; p++) {
        if (*p == '{') {
            if (brace_count == 0) {
                first_brace = p;  // 记录最外层的 '{'
            }
            brace_count++;  // 计数器加 1
        } else if (*p == '}') {
            brace_count--;  // 计数器减 1
            if (brace_count == 0) {
                last_brace = p;  // 记录最外层的 '}'
                break;           // 找到最外层的边界，退出循环
            }
        }
    }

    if (first_brace == NULL || last_brace == NULL || brace_count != 0) {
        return -1;  // 未找到有效的 JSON 边界
    }

    *start = first_brace;
    *end = last_brace;
    return 0;
}
/**字符串转换为16进制数据*/
/**
 * @brief 将Modbus协议十六进制字符串转换为二进制数组
 *
 * @param command 输入字符串，必须为偶数长度且仅包含十六进制字符（0-9, a-f, A-F）
 * @param output 输出缓冲区，必须有足够空间存储 (strlen(command)/2) 字节
 * @param output_len 成功时返回转换后的字节数，失败时设置为0
 *
 * @note 错误处理逻辑：
 *   - 输入指针为NULL
 *   - 空字符串或奇数长度
 *   - 包含非十六进制字符
 *   - 输出缓冲区长度不足（通过strlen计算）
 */
static void ml_parse_hex_command(const char *command, char *output, uint8_t *output_len) {
    // 初始化输出长度为0（默认错误状态）
    if (output_len != NULL) *output_len = 0;

    // ------------ 参数有效性校验 ------------
    // 防御性编程：所有指针必须有效
    if (command == NULL || output == NULL || output_len == NULL) return;

    // ------------ 输入基础校验 ------------
    const size_t command_len = strlen(command);
    if (command_len == 0 || command_len % 2 != 0) return;  // 空字符串或奇数长度

    // ------------ 字符合法性校验 ------------
    // 预校验所有字符均为合法十六进制（避免部分转换后失败）
    for (size_t i = 0; i < command_len; ++i) {
        if (!isxdigit((unsigned char)command[i])) return;
    }

    // ------------ 核心转换逻辑 ------------
    const size_t target_len = command_len / 2;
    for (size_t i = 0; i < target_len; ++i) {
        // 获取两个字符并转换为大写（兼容大小写输入）
        const char c_high = (char)toupper(command[2 * i]);
        const char c_low = (char)toupper(command[2 * i + 1]);

        // 手动转换十六进制（比strtol更高效）
        unsigned char value = 0;
        value |= (c_high >= 'A') ? (c_high - 'A' + 10) << 4 : (c_high - '0') << 4;
        value |= (c_low >= 'A') ? (c_low - 'A' + 10) : (c_low - '0');

        output[i] = value;
    }

    // 只有所有校验通过才更新输出长度
    *output_len = target_len;
}

/**
 * @brief 从 +QMTRECV 消息中提取 topic 字段
 * @param message 输入字符串，格式: +QMTRECV:
 * <client_idx>,<msg_id>,"<topic>",<payload_len>,"<payload>"
 * @param topic 输出缓冲区，用于存储提取的 topic（需提前分配足够空间）
 * @return true 成功提取，false 失败
 */
bool ml_extract_topic(const char *message, char *topic) {
    if (!message || !topic) return false;

    
    const char *first_quote = strchr(message, '"');
    if (!first_quote) return false;

    // 查找第二个双引号（"publish" 的结尾）
    const char *second_quote = strchr(first_quote + 1, '"');
    if (!second_quote) return false;

   
    const char *third_quote = strchr(second_quote + 1, '"');
    if (!third_quote) return false;

   
    const char *fourth_quote = strchr(third_quote + 1, '"');
    if (!fourth_quote) return false;

    // 计算 topic 长度
    size_t topic_len = fourth_quote - (third_quote + 1);
    if (topic_len == 0) return false;

    // 复制 topic 到输出缓冲区
    strncpy(topic, third_quote + 1, topic_len);
    topic[topic_len] = '\0';  // 确保字符串终止

    return true;
}
/**
 * @brief 解析 JSON 并提取 value、length 和 type
 * @param json_str 输入的 JSON 字符串
 * @param value 输出缓冲区，存储提取的 value 字符串
 * @param len 输出 value 的长度
 * @param type 输出 type 字段的值
 * @return 0 成功，-1 失败
 */
int ml_json_decode(const char *json_str, char *value, uint8_t *len, uint8_t *type) {
    if (!json_str || !value || !len || !type) return -1;

    cJSON *root = cJSON_Parse(json_str);
    if (!root) {
        printf("JSON 解析失败\n");
        return -1;
    }

    // 提取 type 字段
    cJSON *type_item = cJSON_GetObjectItem(root, "type");
    if (cJSON_IsNumber(type_item)) {
        *type = (uint8_t)type_item->valueint;
    } else {
        cJSON_Delete(root);
        return -1;
    }
    // 提取 value 字段
    cJSON *value_item = cJSON_GetObjectItem(root, "value");
    if (cJSON_IsString(value_item) && value_item->valuestring != NULL) {
        strncpy(value, value_item->valuestring, strlen(value_item->valuestring));
        *len = (uint8_t)strlen(value_item->valuestring);
        value[*len] = '\0';  // 确保字符串终止
    } else {
        cJSON_Delete(root);
        return -1;
    }

    cJSON_Delete(root);
    return 0;
}

uint8_t ml_uart_decode_urc_cb(void *Ptx, uint8_t *dataBuf, uint8_t data_len,uint8_t *cmd_UrcString) {
    char topic[256];
    char cmd[256];
    char cmd_hex[256];
    char *json_start = NULL;
    char *json_end = NULL;
    uint8_t len, len_hex, type;
    uint16_t index = 5;  // 默认无效值

    // 1. 提取 JSON
    if (ml_find_outer_json_boundaries((char *)dataBuf, &json_start, &json_end) != 0) {
        return 0;
    }
    size_t json_len = json_end - json_start + 1;
    if (json_len >= sizeof(topic)) {  // 防止溢出
        return 0;
    }
    char *json_str = AT_MALLOC(json_len + 1);
    if (!json_str) return 0;
    snprintf(json_str, json_len + 1, "%.*s", (int)json_len, json_start);

    // 2. 解析 JSON 和 Topic
    if (ml_json_decode(json_str, cmd, &len, &type) != 0) {
        AT_FREE(json_str);
        return 0;
    }
    if (ml_extract_topic((const char *)dataBuf, topic) == false) {
        AT_FREE(json_str);
        return 0;
    }

    // 3. 处理十六进制数据
    if (type == 0) {
        ml_parse_hex_command(cmd, cmd_hex, &len_hex);
        len = len_hex;
    }

    // 4. 匹配 Topic
    for (int i = 0; i < ml307_cfg.ml307_mqttc_num; i++) {
        
        if (ml307_cfg.smqtt[i].topic_mux==0) {
            if (strcmp(topic, ml307_cfg.smqtt[i].SubTopic[0].subtopic) == 0) {
                index = i;
                break;
            }
        } else {
            for (int j = 0; j < 3; j++) {
                if (
               strcmp(topic, ml307_cfg.smqtt[i].SubTopic[j].subtopic) == 0) {
                    index = i;
                    break;
                }
            }
            if (index != ml307_cfg.ml307_mqttc_num) break;
        }
    }

    // 5. 分发数据
    if (index >= ml307_cfg.ml307_mqttc_num) {
        printf("[WARN] Unknown topic: %s\n", topic);
        AT_FREE(json_str);
        return 0;
    }
    switch (index) {
        case 0:
            ml_mqttc_sned_other_interface_1(type ? cmd : cmd_hex, len);
            break;
        case 1:
            ml_mqttc_sned_other_interface_2(type ? cmd : cmd_hex, len);
            break;
        case 2:
            ml_mqttc_sned_other_interface_3(type ? cmd : cmd_hex, len);
            break;
        case 3:
            ml_mqttc_sned_other_interface_4(type ? cmd : cmd_hex, len);
            break;
    }

    AT_FREE(json_str);
    return 1;
}

size_t hexstr_to_bytes(const char *hexStr, uint8_t *outBuf, size_t maxLen) {
    size_t len = strlen(hexStr);
    if (len % 2 != 0 || len / 2 > maxLen) return 0;

    for (size_t i = 0; i < len / 2; i++) {
        char byteStr[3] = { hexStr[i * 2], hexStr[i * 2 + 1], '\0' };
        if (!isxdigit(byteStr[0]) || !isxdigit(byteStr[1])) return 0;
        outBuf[i] = (uint8_t)strtol(byteStr, NULL, 16);
    }

    return len / 2;
}


//数据直接透传
uint8_t ml_uart_decode_urc_cb_a(void *Ptx, uint8_t *dataBuf, uint8_t data_len, uint8_t *cmd_UrcString) {
    char topic[128] = {0};
    char payload_str[256] = {0};
    uint16_t payload_len = 0;
    uint16_t index = 5;

    const char *start = strstr((char *)dataBuf, "+MQTTURC: \"publish\"");
    if (!start) return 0;

   
    for (int i = 0; i < 3; i++) {
        start = strchr(start, ',');
        if (!start) return 0;
        start++;
    }

    
    const char *topic_start = strchr(start, '"'); if (!topic_start) return 0;
    topic_start++;
    const char *topic_end = strchr(topic_start, '"'); if (!topic_end) return 0;
    int topic_len = topic_end - topic_start;
    if (topic_len >= sizeof(topic)) return 0;
    memcpy(topic, topic_start, topic_len);
    topic[topic_len] = '\0';

    
    start = topic_end + 1;
    for (int i = 0; i < 2; i++) {
        start = strchr(start, ','); if (!start) return 0;
        start++;
    }
    payload_len = (uint16_t)atoi(start);

   
    start = strchr(start, ','); if (!start) return 0;
    start++;

    memcpy(payload_str, start, payload_len);
    payload_str[payload_len] = '\0';

   
    for (int i = 0; i < ml307_cfg.ml307_mqttc_num; i++) {
        if (ml307_cfg.smqtt[i].topic_mux == 0) {
            if (strcmp(topic, ml307_cfg.smqtt[i].SubTopic[0].subtopic) == 0) {
                index = i;
                break;
            }
        } else {
            for (int j = 0; j < 3; j++) {
                if (strcmp(topic, ml307_cfg.smqtt[i].SubTopic[j].subtopic) == 0) {
                    index = i;
                    break;
                }
            }
            if (index != ml307_cfg.ml307_mqttc_num) break;
        }
    }

    if (index >= ml307_cfg.ml307_mqttc_num) return 0;
		
		if(payload_str[0] == '['){// JSON 类型
		  switch(index) {
        case 0:
            printf("data=%s len=%d\r\n", payload_str, payload_len);
            ml_mqttc_sned_other_interface_1(payload_str, payload_len);
            break;
        case 1: 
            ml_mqttc_sned_other_interface_2(payload_str, payload_len); 
            break;
        case 2: 
            ml_mqttc_sned_other_interface_3(payload_str, payload_len);
            break;
        case 3:
            ml_mqttc_sned_other_interface_4(payload_str, payload_len);
            break;
       }
		
		}
		else{
		
				switch(index) {
						case 0:
								printf("HEX: "); for (size_t i = 0; i < payload_len; i++) printf("%02X ", payload_str[i]); printf("\r\n");
								ml_mqttc_sned_other_interface_1(payload_str, payload_len);
								break;
						case 1: 
								 ml_mqttc_sned_other_interface_2(payload_str, payload_len); 
								break;
						case 2: 
								 ml_mqttc_sned_other_interface_3(payload_str, payload_len);
								break;
						case 3:
								ml_mqttc_sned_other_interface_4(payload_str, payload_len);
								break;
				}
		}
    return 1;
}

void ml_json_parse_Task(void *parameter) {
    while (1) {
        ml_mqtt_modbus_urc_decode(ML307R, ml_uart_decode_urc_cb_a, (uint8_t *)"publish");
        vTaskDelay(1);
    }
}

void ml307_task_create(void) {
	  
    xTaskCreate(ml_Task, "ML307_up", 1024, NULL, 1, &ml_upload_Handle); 
    xTaskCreate(ml_json_parse_Task, "ML307_decode", 500, NULL, 1, &ml_json_parse_Handle);
}